/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.muni.fi.pa165.ddtroops.web.actionbeans;

import cz.muni.fi.pa165.ddtroops.dto.HeroDTO;
import cz.muni.fi.pa165.ddtroops.dto.SquadDTO;
import cz.muni.fi.pa165.ddtroops.dto.UserDTO;
import cz.muni.fi.pa165.ddtroops.serviceinterfaces.HeroService;
import cz.muni.fi.pa165.ddtroops.serviceinterfaces.SquadService;
import cz.muni.fi.pa165.ddtroops.serviceinterfaces.UserService;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import net.sourceforge.stripes.action.*;
import net.sourceforge.stripes.controller.LifecycleStage;
import net.sourceforge.stripes.integration.spring.SpringBean;
import net.sourceforge.stripes.validation.LocalizableError;
import net.sourceforge.stripes.validation.Validate;
import net.sourceforge.stripes.validation.ValidateNestedProperties;
import net.sourceforge.stripes.validation.ValidationErrors;
import org.apache.log4j.Logger;

/**
 *
 * @author newohybat
 */

@UrlBinding("/squads/{$event}/{squad.id}")
public class SquadActionBean implements ActionBean{
    static Logger log = Logger.getLogger(HeroActionBean.class);

    private ActionBeanContext context;
    @SpringBean(value="squadWebService")
    private SquadService service;
    @SpringBean(value="heroWebService")
    private HeroService heroService;
    @SpringBean(value="userWebService")
    private UserService userService;
    @Override
    public void setContext(ActionBeanContext abc) {
        context=abc;
    }

    @Override
    public ActionBeanContext getContext() {
        return context;
    }

    @DefaultHandler
    public Resolution neco(){
        return new ForwardResolution("/squads.jsp");
    }
    public Set<SquadDTO> getSquads(){
        if (getContext().getRequest().isUserInRole("ROLE_SUPERVISOR")) return new HashSet<SquadDTO>(service.getAll());
        else
        {
            UserDTO user = userService.getByName(getContext().getRequest().getRemoteUser());
            List<SquadDTO> squads = service.getAll();
            Set<SquadDTO> result = new HashSet<SquadDTO>();
            for (SquadDTO s : squads) {
                List<String> owners = new ArrayList<String>();
                for (HeroDTO u : s.members) {
                    if(u.user.name.equals(user.name)) result.add(s);
                }
                if(s.getLeader().user.name.equals(user.name)) result.add(s);
            }
            return result;
        }
    }
    
    public boolean isMemberOwner(Long id, String username){
        List<SquadDTO> squads = service.getAll();
        SquadDTO s = service.getById(id);
        UserDTO user = userService.getByName(username);
        List<String> owners = new ArrayList<String>();
        if(s.leader.user.name.equals(user.name)) return false;
        for (HeroDTO u : s.members) {
            if(u.user.name.equals(user.name)) return true;
        }
        return false;
    }
    
    private HeroDTO leader;

    public HeroDTO getLeader() {
        return leader;
    }

    public void setLeader(HeroDTO leader) {
        this.leader = leader;
    }

    public Resolution add(){
        try{
        log.debug("creating squad");
        squad.setMembers(loadedMembers);
        squad.setLeader(leader);
        service.create(squad);
        return new RedirectResolution(this.getClass(), "all");            
        }catch(java.lang.NullPointerException e){
            ValidationErrors errs = new ValidationErrors();
            errs.add("membersCount", new LocalizableError("validation.membersCount.noMember"));
            context.setValidationErrors(errs);
            return context.getSourcePageResolution();
        }
        
    }
    private List<HeroDTO> loadedMembers = new ArrayList<HeroDTO>();
    @Before(stages = LifecycleStage.BindingAndValidation, on = {"add","edit","save"})
    public void loadMembersFromDb(){
        log.debug("loading members from db");
        String[] ids = context.getRequest().getParameterValues("squad.members");
        if (ids == null){
            log.debug("squad.members null");
            return;
        }
        for(String id:ids){
            loadedMembers.add(heroService.getById(Long.parseLong(id)));
        }
        String leaderId = context.getRequest().getParameter("squad.leader");
        if(leaderId == null){
            log.debug("leaderId is null");
            return;
        }
        leader = heroService.getById(Long.parseLong(leaderId));
    }

    public Resolution delete(){
        log.debug("deleting squad");
        service.delete(squad);
        return new RedirectResolution(this.getClass(), "all");

    }
    private List<HeroDTO> heroes= new ArrayList<HeroDTO>();

    public List<HeroDTO> getHeroes() {
        if(heroes.isEmpty()){
            loadHeroes();
        }
        return heroes;
    }

    public void setHeroes(List<HeroDTO> heroes) {
        this.heroes = heroes;
    }
    @Before(stages = LifecycleStage.BindingAndValidation, on = {"add","edit"})
    public void loadHeroes(){
        log.debug("getting all heroes");
        List<HeroDTO> thisHeroes = heroService.getAll();
        for(HeroDTO h : thisHeroes){
            if(service.getSquadOfHero(h)==null){
                heroes.add(h);
            }
        }
    }
    private List<HeroDTO> members;

    public List<HeroDTO> getMembers() {
        return members;
    }

    public void setMembers(List<HeroDTO> members) {
        this.members = members;
    }

    @Before(stages = LifecycleStage.BindingAndValidation, on = {"edit", "save", "delete"})
    public void loadSquadFromDb(){
        log.debug("loading squad from db");
        String ids = context.getRequest().getParameter("squad.getId()");
        if (ids == null) return;
        squad = service.getById(Long.parseLong(ids));
        heroes.addAll(squad.getMembers());
        }

    public Resolution edit(){
        return new ForwardResolution("/squadsEdit.jsp");
    }

    public Resolution save(){

        log.debug("saving squad");
        squad.setMembers(loadedMembers);
        squad.setLeader(leader);
        service.update(squad);
        return new RedirectResolution(this.getClass(), "all");
    }

    private SquadDTO squad;
    
    @ValidateNestedProperties(
        value= {
            @Validate(on={"add", "save"},field="name", required=true),
            @Validate(on={"add", "save"},field="description", required=true),
            @Validate(on={"add", "save"},field="task", required=true),
            @Validate(on={"add", "save"},field="gold", required=true, minvalue=0)
        }
    )
    
    public SquadDTO getSquad(){
        return squad;
    }

    public void setSquad(SquadDTO squad){
        this.squad = squad;
    }

}
